/**
 * @file elf.h
 * @date 23.05.01
 * @author xin
 * @brief ELF可执行文件的格式化
 * @version 0.1
 * @status Stable
*/

#include "types.h"

#define ELF_MAGIC   0x464C457FU     // 小端

// 文件头
struct elfhdr {
    uint magic;         // 魔数，必须等于ELF_MAGIC
    uchar elf[12];      // 类型等信息
    ushort type;        // 文件类型，如可执行文件、目标文件等
    ushort machine;     // 目标机器类型
    uint version;       // 文件版本
    uint64 entry;       // 程序入口地址
    uint64 phoff;       // program header表在文件中的偏移
    uint64 shoff;       // section header表在文件中的偏移
    uint flags;         // 一些标识信息
    ushort ehsize;      // elf header大小
    ushort phentsize;   // program header表中每个条目大小
    ushort phnum;       // program header表中条目数量
    ushort shentsize;   // section header表中每个条目大小
    ushort shnum;       // section header表中条目数量
    ushort shstrndx;    // 包含节名称字符串表的节头索引
};

// 程序段头部
// 程序头表项描述了一个加载段(Loadable Segment)在可执行文件中的位置和大小信息
struct proghdr
{
    // 这个程序头表项的类型，可能的值：PT_NULL, PT_LOAD, PT_DYNAMIC, PT_INTERP, PT_NOTE, PT_SHLIB, PT_PHDR等
    uint32 type;    
    uint32 flags;   // 程序头表项的标志信息
    uint64 off;     // 程序头表项的第一个字节在文件中的偏移量
    uint64 vaddr;   // 程序头表项的第一个字节在内存中的虚拟地址
    uint64 paddr;   // 程序头表项的第一个字节在内存中的物理地址
    uint64 filesz;  // 程序头表项在文件中的大小（字节）
    uint64 memsz;   // 程序头表项在内存中的大小（字节）
    uint64 align;   // 程序头表项在文件和内存中的对齐方式
};

// proghdr类型的值
#define ELF_PROG_LOAD       1

// proghdr的flags的标志位
#define ELF_PROG_FLAG_EXEC  1
#define ELF_PROG_FLAG_WRITE 2
#define ELF_PROG_FLAG_READ  4

